package com.weetop.aklyscan.utils;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.widget.ArrayAdapter;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BlueToothSolve {

    private static final String TAG = "BlueToothSolve";

    private Context mContext;
    private volatile static BlueToothSolve mInstance;

    private BlueToothListener listener;

    private final static String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";   //SPP服务UUID号
    private BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();    //获取本地蓝牙适配器，即蓝牙设备
    private BluetoothListenerReceiver bTreceiver;
    private BluetoothAdapter mBtAdapter;
    private BluetoothDevice _device = null;     //蓝牙设备
    private BluetoothSocket _socket = null;      //蓝牙通信socket
    private InputStream btIs; //蓝牙输入流
    private OutputStream btOs; //蓝牙输出流
    private boolean conState = false; //是否连接

    private List<String> bTdeviceList;
    private ArrayAdapter<String> bTdeviceAdapter;

    //蓝牙数据读取以及连接线程池
    ExecutorService btThreadPool = Executors.newFixedThreadPool(2);

    public boolean getconState(){return conState;}
    public ArrayAdapter<String> getbTdeviceAdapter(){return bTdeviceAdapter;}
    public BluetoothListenerReceiver getbTreceiver(){return bTreceiver;}

    private BlueToothSolve(Context context){
        Log.e(TAG, "BlueToothSolve创建");
        this.mContext = context;

        //注册蓝牙监听
        bTreceiver = new BluetoothListenerReceiver();
        //初始化适配器
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();

        bTdeviceList = new ArrayList<>();
        bTdeviceAdapter = new ArrayAdapter<String>(mContext, android.R.layout.simple_list_item_1, bTdeviceList);

        //发送及接收线程
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                while (true){
                    try{
                        if(conState){ //连接成功
                            if(revData())
                                listener.request();
                            else{
                                Log.w(TAG, "wait...");
                                Thread.sleep(10); //串口无数据
//                                listener.request(); //测试
                            }
                        }
                    }catch (IOException e){
                        //
                    }catch (InterruptedException e){
                        //
                    }
                }
            }
        };
        btThreadPool.execute(runnable);

    }

    public static BlueToothSolve getInstance(Context context){
        if(mInstance == null){
            mInstance = new BlueToothSolve(context);
        }

        return mInstance;
    }

    public class BluetoothListenerReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (Objects.requireNonNull(intent.getAction())) {
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
                    switch (blueState) {
                        case BluetoothAdapter.STATE_TURNING_ON:
                            Log.w(TAG, "onReceive---------蓝牙正在打开中");
                            break;
                        case BluetoothAdapter.STATE_ON:
                            Log.w(TAG, "onReceive---------蓝牙已经打开");
                            //蓝牙开启，开始查找设备
                            searchBlueTooth();
                            break;
                        case BluetoothAdapter.STATE_TURNING_OFF:
                            Log.w(TAG, "onReceive---------蓝牙正在关闭中");
                            break;
                        case BluetoothAdapter.STATE_OFF:
                            Log.w(TAG, "onReceive---------蓝牙已经关闭");
                            closeDevice();
                            break;
                    }
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    Log.w(TAG, "onReceive---------搜索结束!");
                    listener.overDiscovery();
                    break;
                case BluetoothDevice.ACTION_ACL_DISCONNECTED:
                    Log.w(TAG, "onReceive---------连接丢失!");
                    closeDevice();
                    listener.disConn();
                    break;
                case BluetoothDevice.ACTION_FOUND:
//                    Log.w(TAG, "onReceive---------发现设备!");
                    // 得到蓝牙设备
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    //与本地存储地址匹配
                    //local device
                    //更新设备信息
//                    BlueToothDeviceInfo info = new BlueToothDeviceInfo();
//                    assert device != null;
//                    info.setName(device.getName());
//                    info.setAddr(device.getAddress());
//                    listener.updateDevice(info);

//                    assert device != null;
                    String info = device.getName() + "\n" + device.getAddress();

                    if(!bTdeviceList.contains(info)){
                        bTdeviceList.add(info);
                        bTdeviceAdapter.notifyDataSetChanged();
                    }

                    break;
            }

        }
    }

    //方法
    public boolean enableBlueTooth(){
        if(_bluetooth != null && !_bluetooth.isEnabled()) {
            return _bluetooth.enable();
        }
        return true;
    }

    public boolean disableBlueTooth(){
        if(_bluetooth != null){
            return _bluetooth.disable();
        }
        return true;
    }

    //蓝牙状态监听
    public IntentFilter makeFilter() {
        IntentFilter filter = new IntentFilter();
        // 监视蓝牙打开及关闭状态
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        // 监视蓝牙设备与APP连接的状态
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        // 开始查找以及结束查找
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        // 发现设备
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        return filter;
    }

    public void searchBlueTooth(){
        //先关闭
        stopSearchBlueTooth();
        //重新查找
        mBtAdapter.startDiscovery();
        Log.w(TAG, "startDiscovery...");
    }

    public void stopSearchBlueTooth(){
        if (mBtAdapter.isDiscovering()) {
            mBtAdapter.cancelDiscovery();
        }

        //清空之前获取的设备列表
        if(bTdeviceList != null){
            bTdeviceList.clear();
            bTdeviceAdapter.notifyDataSetChanged();
        }

        Log.w(TAG, "stopDiscovery...");
    }

    public void closeDevice(){
        try{
            if(_socket != null && _socket.isConnected()){
                _socket.close();
                _socket = null;

                btOs.close();
                btOs = null;

                btIs.close();
                btIs = null;

            }
        }catch (IOException e){
            //
        }finally {
            conState = false;
        }
    }

    public void connectDevice(int id){
        //获取蓝牙设备
        String info = bTdeviceList.get(id);
        String name = info.split("\n")[0].trim(); //名字
        String addr = info.split("\n")[1].trim(); //地址
        _device = _bluetooth.getRemoteDevice(addr);
        //socket连接
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try{
                    _socket = _device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
                    _socket.connect();

                    //获取蓝牙输入输出流
                    btIs = _socket.getInputStream();
                    btOs = _socket.getOutputStream();

                    conState = true;
                    listener.connSuccess(name);
                }catch (IOException e){
                    Log.e(TAG, "连接失败!");

                    conState = false;
                    listener.connFailed(name);
                }
            }
        };
        btThreadPool.execute(runnable);
    }

    public void unRegBtReceiver(){
        //注销
        mContext.unregisterReceiver(bTreceiver);
    }

    //接口
    public interface BlueToothListener{
        void overDiscovery();
        void connSuccess(String name);
        void connFailed(String name);
        void disConn();
        void request();
    }

    public void setListener(BlueToothListener listener){
        this.listener = listener;

        //注册
        mContext.registerReceiver(bTreceiver, makeFilter());
    }
    public BlueToothListener getListener(){return listener;}

    /**
     * @发送数据 字符串
     * @param message
     */
    public void senData(String message){
        try{

            if(_socket != null && btOs != null){
                btOs.write(message.getBytes("GBK"));
            }
        }catch (Exception e){
            Log.e(TAG, e.toString());
        }
    }

    /**
     * @发送数据 字节数组
     * @param message
     */
    public void sendDataBytes(byte[] message)
    {
        try
        {
            if(_socket != null && btIs != null)
            {
                btOs.write(message);
            }
        }
        catch (Exception e)
        {
            Log.e(TAG, e.toString());
        }
    }

    //读取串口请求
    private boolean revData() throws IOException{
//        while (btIs.available() > 0){
//            int count = btIs.available();
//
//            //判断包长度
//            if(count < BlueToothData.Cmd.req_len)
//                return false;
//
//            byte[] buffer = new byte[count];
//            int len = btIs.read(buffer);
//
//            return (len == BlueToothData.Cmd.req_len && Arrays.equals(buffer, BlueToothData.Cmd.request));
//
//        }

        return false;
    }
}